package edu.hnu.cloudflightserver.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/***
 * 2012-06-07 20:38:25,405 [catalina-exec-4]  INFO (amazon.HttpHelper) - hard_disk_size-uom  333
 * 
 * %d [%t] %5p (%C{2}) - %m%n
 * 
 * ==>  %d [%t] %5p - %m%n
 * @author Administrator
 *
 */
public class LogUtil {
	private static final Logger log = LoggerFactory.getLogger("");
	
	private static Map<Long,String> bids;
	
	static{
		bids=new HashMap<Long,String>();
	}
	
	/***
	 * 入口启动
	 * @param 
	 */
	@SuppressWarnings("rawtypes")
	public static String start(Class cls,String tag){
		if(bids==null)bids=new HashMap<Long,String>();
		String id=RandomStringUtil.randomNumeric(10);
		bids.put(Thread.currentThread().getId(), id);
		info(id,cls.getSimpleName(),tag);
		return id;
	}
	/***
	 * 入口退出
	 */
	@SuppressWarnings("rawtypes")
	public static void end(Class cls){
		if(bids==null)bids=new HashMap<Long,String>();
		String id=bids.remove(Thread.currentThread().getId());
		if(id==null){
			id=start(cls,"");
		}
		info(id,cls.getSimpleName());
	}
	/***
	 * 方法调用之前-没有输入可写
	 */
	@SuppressWarnings("rawtypes")
	public static void input(Class cls,String method){
		input(cls,method,null);
	}
	/***
	 * 方法调用之前
	 */
	@SuppressWarnings("rawtypes")
	public static void input(Class cls,String method,LMap map){
		if(bids==null)bids=new HashMap<Long,String>();
		String id=bids.get(Thread.currentThread().getId());
		if(id==null){
			id=start(cls,method);
		}
		info(id,cls.getSimpleName(),method,"[begin]",map==null?"":map.toString());
	}
	/***
	 * 方法调用之后-没有输出可写
	 */
	@SuppressWarnings("rawtypes")
	public static void output(Class cls,String method){
		output(cls,method,null);
	}
	/***
	 * 方法调用之后
	 */
	@SuppressWarnings("rawtypes")
	public static void output(Class cls,String method,LMap map){
		if(bids==null)bids=new HashMap<Long,String>();
		String id=bids.get(Thread.currentThread().getId());
		if(id==null){
			id=start(cls,method);
		}
		info(id,cls.getSimpleName(),method,"[end]",map==null?"":map.toString());
	}
	/***
	 * 方法异常退出
	 * @param cls
	 * @param method
	 * @param t
	 */
	@SuppressWarnings("rawtypes")
	public static void warn(Class cls, String method, Throwable e) {
		warn(cls,method,e,null);
	}
	@SuppressWarnings("rawtypes")
	public static void warn(Class cls, String method, String text) {
		warn(cls,method,null,LMap.getInstance().with("text", text));
	}
	/***
	 * 方法异常退出
	 * @param cls
	 * @param method
	 * @param t
	 */
	@SuppressWarnings("rawtypes")
	public static void warn(Class cls, String method, Throwable e,LMap map) {
		if(bids==null)bids=new HashMap<Long,String>();
		String id=bids.get(Thread.currentThread().getId());
		if(id==null)id="";
		/*if(e!=null){
			try{
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				PrintStream ps = new PrintStream(baos);  
				e.printStackTrace(ps);  
				String errContent = baos.toString();
				
				String path = Common.FILE_PATH+Common.ERROR_PATH+DateUtil.getNow(DateUtil.format3)+".log";
				FileWriter fw = new FileWriter(path, true);
				fw.write("\nThread "+id+"'s exception message:\n");
				fw.write(errContent);
				fw.close();
			}catch(Exception e1){
				
			}
			e.printStackTrace();
		}*/
		warn(id,cls.getSimpleName(),method,"[error]",map==null?"":map.toString(),e==null?"":e.getMessage());
	}
	@SuppressWarnings("rawtypes")
	public static void debug(Class cls, String method,int num){
		debug(cls,method,String.valueOf(num));
	}
	/***
	 * 方法内的debug
	 * @param txts
	 */
	@SuppressWarnings("rawtypes")
	public static void debug(Class cls, String method,String... txts){
		if(bids==null)bids=new HashMap<Long,String>();
		String id=bids.get(Thread.currentThread().getId());
		if(id==null)id="";
		log.debug(cls.getSimpleName()+" "+method+" "+id+" "+StringUtils.join(txts," "));
	}

	public static void info(String... txts){
		log.info(StringUtils.join(txts," "));
	}
	private static void warn(String... txts){
		log.warn(StringUtils.join(txts," "));
	}
	public static class LMap{
		public static LMap getInstance(){
			return new LMap();
		}
		private List<String> keys;
		private List<Object> vals;
		
		public LMap(){
			this.keys=new ArrayList<String>();
			this.vals=new ArrayList<Object>();
		}
		public LMap with(String key,Object val){
			keys.add(key);
			vals.add(val);
			return this;
		}
		@Override
		public String toString(){
			StringBuilder sb = new StringBuilder();
			for(int i=0;i<keys.size();i++){
				Object val=vals.get(i);
				sb.append("(");
				sb.append(keys.get(i));
				sb.append(":");
				if(val==null){
					sb.append("NULL");
				}
				else{
					if(val.getClass().getName().endsWith("List")){
						sb.append(((List<?>)val).size());
					}
					else if(val.getClass().getName().endsWith("Map")){
						sb.append(((Map<?,?>)val).size());
					}
					else {
						sb.append(val.toString());
					}
				}
				sb.append(")");
			}
			return sb.toString();
		}
	}
	public static String notnull(Object item){
		return item==null?"not null":"null";
	}
	
	public static LMap flag(boolean flag){
		return LMap.getInstance().with("flag", flag);
	}
}
